package com.sicnu.gateway.filters;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.sicnu.gateway.config.WhiteListConfig;
import com.sicnu.gateway.dto.TokenDTO;
import com.sicnu.gateway.enums.CodeEnum;
import com.sicnu.gateway.ex.BizEx;
import com.sicnu.gateway.util.JwtUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    @Autowired
    private WhiteListConfig whiteListConfig;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getPath().value();
        ServerHttpRequest request = exchange.getRequest();

        // 精确匹配白名单路径
        List<String> whiteList = whiteListConfig.getWhiteList();
        if (isWhiteListed(whiteList,path)) { // 白名单路径直接放行
            return chain.filter(exchange);
        }

        // 获取请求头中的 Authorization 字段
        List<String> headers = request.getHeaders().get("authorization");
        if (headers == null || headers.isEmpty()) {
            // 如果没有携带 token，则返回 401 Unauthorized
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            System.out.println("没有token");
            return exchange.getResponse().setComplete();
        }

        // 获取 token（去除 "Bearer " 前缀）
        String token = headers.get(0);
        System.out.println("token:" + token);

        // 验证 token 并解析用户信息
        try {
            // 验证Token并解码
            DecodedJWT decodedJWT = JwtUtil.verify(token);
            // 解析为TokenDTO对象
            TokenDTO tokenDTO = JwtUtil.parse(decodedJWT, TokenDTO.class);
            if (tokenDTO == null || tokenDTO.getId() == null) {
                throw new BizEx(CodeEnum.AUTH_ERR);
            }
            Long userId = tokenDTO.getId();
            System.out.println("userId:" + userId);
            // 将用户信息添加到请求头
            ServerHttpRequest modifiedRequest = request.mutate()
                    .header("X-User-Id", String.valueOf(userId))
                    .build();

            return chain.filter(exchange.mutate().request(modifiedRequest).build());
        } catch (BizEx e) {
            // 处理自定义业务异常（如Token无效）
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        } catch (Exception e) {
            // 其他异常处理
            exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            return exchange.getResponse().setComplete();
        }
    }

    public static boolean isWhiteListed(List<String> whiteList,String requestUrl) {
        if (ObjectUtils.isEmpty(whiteList)) {
            return false;
        }
        PathMatcher pathMatcher = new AntPathMatcher();
        for (String pattern : whiteList) {
            if (pathMatcher.match(pattern, requestUrl)) {
                return true; // 匹配成功，无需过滤
            }
        }
        return false; // 不在白名单中，需要过滤
    }

    @Override
    public int getOrder() {
        return 2; // 设置优先级（值越小优先级越高）
    }
}